import 'package:flutter/material.dart';

class AnimatedBuilderPage extends StatefulWidget {
  const AnimatedBuilderPage({Key? key}) : super(key: key);

  @override
  State<AnimatedBuilderPage> createState() => _AnimatedBuilderPageState();
}

class _AnimatedBuilderPageState extends State<AnimatedBuilderPage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  final message = "just to test" * 20;
  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 5))
          ..repeat();
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('AnimatedBuilder'),
        ),
        body: Column(
          children: [
            const Padding(
              padding: EdgeInsets.all(20.0),
              child: Text("1、AnimatedBuilder"),
            ),
            Container(
              color: Colors.green,
              width: double.infinity,
              padding: const EdgeInsets.all(20.0),
              child: const TypeWriter(),
            ),
            const Padding(
              padding: EdgeInsets.all(20.0),
              child: Text("2、AnimatedWidget"),
            ),
            Container(
              color: Colors.red,
              width: double.infinity,
              padding: const EdgeInsets.all(20.0),
              child:
                  TypeWriterTransition(message: message, progress: _controller),
            ),
          ],
        ));
  }
}

class TypeWriter extends StatefulWidget {
  const TypeWriter({Key? key}) : super(key: key);

  @override
  State<TypeWriter> createState() => _TypeWriterState();
}

class _TypeWriterState extends State<TypeWriter>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  final message = "just to test" * 20;
  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 5))
          ..repeat();
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          final count = (message.length * _controller.value).floor();
          final text = message.substring(0, count);
          return Text(
            text,
            style: const TextStyle(fontSize: 24),
          );
        });
  }
}

// AnimateWidget
class TypeWriterTransition extends AnimatedWidget {
  final String message;
  final Animation<double> progress;

  const TypeWriterTransition(
      {Key? key, required this.message, required this.progress})
      : super(key: key, listenable: progress);

  @override
  Widget build(BuildContext context) {
    final count = (message.length * progress.value).floor();
    final text = message.substring(0, count);
    return Text(
      text,
      style: const TextStyle(fontSize: 24),
    );
  }
}
